package com.wang.learn.cloudredis.controller;

import com.alibaba.fastjson.JSONObject;
import com.wang.learn.cloudredis.entity.Book;
import com.wang.learn.cloudredis.utils.ReqDedupHelper;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * ClassName RedisController
 * Description
 *
 * @author wang
 * Date 2021/6/19 10:48
 */
@RestController
@RequestMapping("/redis")
public class RedisController {


    @Resource
    private RedisTemplate<String, Object> stringRedisTemplate;

    @RequestMapping("/repeat")
    public Object repeat(@RequestBody @Valid Book book){
        //用户
        String userId= "12345678";
        //接口名
        String method = "pay";
        //计算请求参数摘要，其中剔除里面请求时间的干扰
        String dedupMD5 = ReqDedupHelper.dedupParamMD5(JSONObject.toJSONString(book),"time");
        String key = "dedup:U=" + userId + "M=" + method + "P=" + dedupMD5;
        // 1000毫秒过期，1000ms内的重复请求会认为重复
        long expireTime =  1000;
        long expireAt = System.currentTimeMillis() + expireTime;

        String val = "expireAt@" + expireAt;
        // 如果key不存在，set并返回true；如果key存在，不做操作返回false
        Boolean firstSet = stringRedisTemplate.opsForValue().setIfAbsent(key, val, expireTime, TimeUnit.MILLISECONDS);

        final boolean isConsiderDup;
        if (firstSet != null && firstSet) {
            return book;
        } else {
            return "订单重复！";
        }
    }

    private String lockKey = "lock_order:";

    @RequestMapping("/setIfAbsent")
    public Object setIfAbsent(){
        String lock = (lockKey + "123456").intern();
        String uuid = UUID.randomUUID().toString();
        boolean redisKeyBoolean = stringRedisTemplate.opsForValue().setIfAbsent(lock, uuid, 15, TimeUnit.SECONDS);
        System.out.println(redisKeyBoolean);
        if(redisKeyBoolean){
            return "抢单成功！";
        }else{
            return "很遗憾！订单已被抢走了";
        }
    }

}
